/**
 * Kernel Monkeys
 * Andrew Boguk
 * Sergiy Kulyk
 * Nicholas Swartzendruber
 */

/*
 * cpu.h
 *
 *  Created on: Jun 7, 2011
 *      Author: Sergiy Kulyk
 */

#ifndef CPU_H_
#define CPU_H_

#include "timer.h"
#include "io_dev.h"
#include "queue.h"
#include "sched.h"



/*****************************************************************************
 *                      P C B
 *****************************************************************************/

/**
 * PCB record.
 */
typedef struct pcb_t {
        int     pid;
        int next_step;          // this is the step count that the CPU had gotten to
                                                // when this process was preempted
        int state;                      // e.g. 0=running, 1=ready, 2=interrupted, 3=blocked
        int waiting_on;         // which queue is it in if it is waiting on something (blocked)
        int owns;                       // which semaphore does it own
        // anything else you need
} pcb_t;

typedef pcb_t* PCBRecord;


/**
 * PCB record constructor. All records are created in the "ready" state, with
 * the 0 for the next instruction to run, not waiting on any values, and not
 * owning any semaphores.
 *
 * @param pid Process ID.
 * @return A pointer to the PCB record.
 */
PCBRecord cpu_new_pcb(const int pid);


/**
 * Set the PCB record to "blocked" state, and register
 * the I/O device it is waiting on.
 *
 * @param pcb The PCB record.
 * @param waiting_on I/O device this process is waiting on.
 */
void cpu_pcb_set_waiting(PCBRecord pcb, const int waiting_on);


/**
 * Set the PCB record to "ready" state, and unregister
 * the I/O device it was waiting on (if any).
 *
 * @param pcb The PCB record.
 */
void cpu_pcb_set_ready(PCBRecord pcb);



/****************************************************************************
 *                      C P U
 ****************************************************************************/

#define MAX_PROCESSES 100
#define MAX_STEPS 1000
#define MAX_REQUESTS 5

#define NUM_IO 3
#define DISK_IO 0
#define VIDEO_IO 1
#define KEY_IO 2

typedef struct cpu_t {
        Scheduler scheduler;    // scheduler instance
        Timer timer;     // timer instance
        int io_num;             // number of I/O devices
        Queue processes;
        Queue pcb_q;
        io_dev io[NUM_IO];      // an array of I/O devices
        Queue block_q[NUM_IO];  // array of block queues - one for each I/O device

} cpu_t;

typedef cpu_t* CPU;


/**
 * CPU constructor.
 *
 */
CPU cpu_new();


/**
 * Run the CPU.
 *
 * @param cpu The CPU to run.
 */
void cpu_run(const CPU cpu);






#endif /* CPU_H_ */
